package cn.isjinhao.se.structure;

/**
 * @Author ISJINHAO
 * @Date 2021/7/6 9:26
 */
public abstract class AbstractRetrieveSupported<K, E extends KeySupported<K>> implements RetrieveSupported<K, E> {

    /**
     * 在指定位置设置数据，允许移动数据
     *
     * @param index
     * @param e
     */
    protected abstract void insertItem(int index, E e);

    /**
     * 在指定位置移除数据，允许移动数据
     *
     * @param index
     * @return
     */
    protected abstract E removeItem(int index);

    /**
     * moveData为false的时候，只有两种情况下可以设置成功：
     * 1、index值为当前最大的index值加一，即index == size()
     * 2、index值对应的位置为null
     * moveData为true的时候，index值在区间[0, size()]中都可以设置成功。
     *
     * @param index
     * @param e
     * @param moveData
     * @return 是否设置成功
     */
    public boolean set(int index, E e, boolean moveData) {
        // add数据的时候允许将数据向后移动
        if (!moveData && (index == size() || (checkIndexInRange(index) && get(index) == null))) {
            insertItem(index, e);
            return true;
        } else if (moveData && checkIndexCanAdd(index)) {
            insertItem(index, e);
            return true;
        }
        return false;
    }

    /**
     * moveData为false的时候，后面的元素会向前移动
     * moveData为true的时候，后面的元素不会向前移动
     *
     * @param index
     * @param moveData
     * @return 移除的值
     */
    public E remove(int index, boolean moveData) {
        if (!checkIndexInRange(index)) {
            return null;
        }
        E value = removeItem(index);
        if (!moveData) {
            insertItem(index, null);
        }
        return value;
    }

}
